package com.atguigu.cloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RateLimitController {

    @GetMapping(value = "/rateLimit/byUrl")
    public String byUrl() {
        return "按rest地址限流测试OK";
    }

    @GetMapping(value = "/rateLimit/byResource")
    @SentinelResource(value = "byResourceSentinelResource", blockHandler = "blockHandler")   // value属性是指定哪个资源动用哨兵进行保护; blockHandler属性是指自定义限流提示
    public String byResource() {
        return "按资源名称SentinelResource限流测试OK";
    }

    public String blockHandler(BlockException blockException) {
        return "服务不可用, 触发了@SentinelResource启动";
    }

    @GetMapping(value = "/rateLimit/doAction/{p1}")
//    blockHandler 和 fallback 可以共存, blockHandler主要针对sentinel配置后出现的违规情况处理, fallback主要针对程序异常JVM抛出的异常服务降级
    @SentinelResource(value = "doActionSentinelResource", blockHandler = "doActionBlockHandler", fallback = "doActionFallback")   // fallback属性是指服务降级处理
    public String doAction(@PathVariable("p1")Integer p1) {
        if (p1 == 0) {
            throw new RuntimeException("p1等于0直接异常");
        }
        return "doAction";
    }

    public String doActionBlockHandler(@PathVariable("p1") Integer p1, BlockException blockException) {
        return "sentinel配置自定义限流了";
    }

    public String doActionFallback(@PathVariable("p1") Integer p1, Throwable throwable) {
        return "程序逻辑异常" + "\t" + throwable.getMessage();
    }

    /**
     * 热点参数限流
     */
    @GetMapping(value = "/hotkey")
    @SentinelResource(value = "hotkey", blockHandler = "handlerBlockHandler")
    public String hostKey(@RequestParam(value = "p1", required = false)String p1, @PathVariable(value = "p2", required = false)String p2) {
        return "---- hotkey";
    }

    public String handlerBlockHandler(String p1, String p2, BlockException exception) {
        return "---- handlerBlockHandler";
    }

}
